/**
 * 教师模块服务文件
 */

const { addTeacher, validAdd, addTeacherRoles, getTeacherByUserName, validRights, validUpdateTeacher, updateTeacher, updateTeacherPassword, getTeacherPasswordById, updateStatus, getTeacherStatusById, searchTeacherList, addEmergencyContact, updateEmergencyContact, deleteEmergencyContact, getEmergencyContacts, searchAvailableTeacherList, searchStatus } = require('../db/teachers');
const { getFirstCourseByTeacherId } = require('../db/course_list');
const { getFirstClassByTeacherId } = require('../db/class_list');
const md5 = require('md5-node');
const { sign } = require('jsonwebtoken');
const { secret, tokenExpired } = require('../config.json');
const { add: addLog } = require('../services/logs');
const { getAge } = require('../utils/common');
const dayjs = require('dayjs');

/**
 * 添加教师
 * @param {*} ctx 上下文
 * @returns 
 */
const add = async (ctx) => {
    try {
        const teacher = ctx.request.body;
        const age = getAge(teacher.idNo);
        if (age < 10) {
            return ctx.body = {
                code: 0,
                msg: '年龄最小为10岁'
            }
        }
        let result = await validAdd(teacher);
        if (result?.idNo === teacher.idNo) {
            return ctx.body = {
                code: 0,
                msg: '已存在相同的身份证号'
            }
        }
        if (result?.work_no === teacher.work_no) {
            return ctx.body = {
                code: 0,
                msg: '已存在相同的工号'
            }
        }
        if (result?.username === teacher.username) {
            return ctx.body = {
                code: 0,
                msg: '已存在相同的用户名'
            }
        }
        const sex = teacher.idNo.at(-2) % 2 === 1 ? '男' : '女';
        teacher.sex = sex;
        teacher.password = md5(teacher.password);
        result = await addTeacher(teacher);
        console.log(result);
        ctx.body = {
            code: 1,
            msg: '教师添加成功',
            data: result.id
        }
    } catch (error) {
        ctx.app.emit('error', error);
        ctx.body = {
            code: 0,
            msg: '教师添加失败'
        }
    }
}

/**
 * 添加教师角色
 * @param {*} ctx 上下文
 */
const addRoles = async (ctx) => {
    try {
        const { teacherId, roleIds } = ctx.request.body;
        const { id } = ctx.state.user;
        if (id === teacherId) {
            return ctx.body = {
                code: 0,
                msg: '无法变更自己的角色'
            }
        }
        await addTeacherRoles(teacherId, roleIds);
        ctx.body = {
            code: 1,
            msg: '角色分配成功'
        }
    } catch (error) {
        ctx.app.emit('error', error);
        ctx.body = {
            code: 0,
            msg: '角色分配失败'
        }
    }
}

/**
 * 修改教师信息
 * @param {*} ctx 
 */
const update = async (ctx) => {
    try {
        const teacher = ctx.request.body;
        const age = getAge(teacher.idNo);
        if (age < 10) {
            return ctx.body = {
                code: 0,
                msg: '年龄最小为10岁'
            }
        }
        const result = await validUpdateTeacher(teacher);
        if (result?.idNo === teacher.idNo) {
            return ctx.body = {
                code: 0,
                msg: '已存在相同的身份证号'
            }
        }
        if (result?.work_no === teacher.work_no) {
            return ctx.body = {
                code: 0,
                msg: '已存在相同的工号'
            }
        }
        const sex = teacher.idNo.at(-2) % 2 === 1 ? '男' : '女';
        teacher.sex = sex;
        await updateTeacher(teacher);
        ctx.body = {
            code: 1,
            msg: '修改成功'
        }
    } catch (error) {
        ctx.app.emit('error', error);
        ctx.body = {
            code: 0,
            msg: '教师信息修改失败'
        }
    }
}

/**
 * 登录
 * @param {*} ctx 
 */
const login = async (ctx) => {
    const { username, password } = ctx.request.body;
    try {
        const teacher = await getTeacherByUserName(username);
        if (!teacher) {
            return ctx.body = {
                code: 0,
                msg: '用户名不存在'
            }
        }
        if (!teacher.status) {
            return ctx.body = {
                code: 0,
                msg: '您已离职，无法登录系统'
            }
        }
        const { id, password: pwd } = teacher;
        if (pwd !== md5(password)) {
            return ctx.body = {
                code: 0,
                msg: '密码错误'
            }
        }
        const token = sign({ id, username }, secret, { expiresIn: tokenExpired });
        teacher.password = token;
        addLog(`${username}登录成功`, false);
        ctx.body = {
            code: 1,
            msg: '登录成功',
            data: teacher
        }
    } catch (error) {
        ctx.app.emit('error', error);
        ctx.body = {
            code: 0,
            msg: '登录失败'
        }
    }
}

/**
 * 校验教师权限
 * @param {*} ctx 
 */
const validTeacherRigths = (teacherId, path) => {
    return validRights(teacherId, path);
}

/**
 * 修改密码
 * @param {*} ctx 
 */
const updatePassword = async (ctx) => {
    try {
        const teacher = ctx.request.body;
        teacher.password = md5(teacher.password);
        const obj = await getTeacherPasswordById(teacher.id);
        if (!obj) {
            return ctx.body = {
                code: 0,
                msg: '要修改的数据不存在'
            }
        }
        if (obj.password === teacher.password) {
            return ctx.body = {
                code: 0,
                msg: '新密码不能跟旧密码一致'
            }
        }
        const result = await updateTeacherPassword(teacher);
        return ctx.body = {
            code: 1,
            msg: '密码修改成功'
        }
    } catch (error) {
        ctx.app.emit('error', error);
        ctx.body = {
            code: 0,
            msg: '密码修改失败，请稍后再试'
        }
    }
}

/**
 * 修改我的密码
 * @param {*} ctx 
 */
const updateMyPassword = async (ctx) => {
    try {
        const teacher = ctx.request.body;
        const { id } = ctx.state.user;
        const self = await getTeacherPasswordById(id);
        teacher.oldPassword = md5(teacher.oldPassword);
        if (self?.password !== teacher.oldPassword) {
            return ctx.body = {
                code: 0,
                msg: '旧密码不正确，请重新输入'
            }
        }
        teacher.id = id;
        teacher.password = md5(teacher.password);
        const result = await updateTeacherPassword(teacher);
        if (result.affectedRows > 0) {
            return ctx.body = {
                code: 1,
                msg: '密码修改成功'
            }
        }
        ctx.body = {
            code: 0,
            msg: '密码修改失败，请稍后再试'
        }
    } catch (error) {
        ctx.app.emit('error', error);
        ctx.body = {
            code: 0,
            msg: '密码修改失败，请稍后再试'
        }
    }
}

/**
 * 变更状态
 * @param {*} ctx 
 */
const changeStatus = async (ctx) => {
    try {
        const body = ctx.request.body;
        const { id, status } = body;
        if (id === ctx.state.user.id) {
            return ctx.body = {
                code: 0,
                msg: '无法修改本人状态'
            }
        }
        let result = await getTeacherStatusById(id);
        if (!result) {
            return ctx.body = {
                code: 0,
                msg: '您要修改的教师信息不存在，请确认后在操作'
            }
        }
        if (result.status === status) {
            return ctx.body = {
                code: 0,
                msg: '状态一致，无需变更'
            }
        }
        if (!status) {
            result = await getFirstClassByTeacherId(id);
            if (result) {
                return ctx.body = {
                    code: 0,
                    msg: `您要修改的教师还是${result.name}的班主任，请替换后再变更状态`
                }
            }
            result = await getFirstCourseByTeacherId(id);
            if (result) {
                const { from_date, end_date } = result;
                return ctx.body = {
                    code: 0,
                    msg: `您要修改的教师在${dayjs(from_date).format('YYYY-MM-DD HH:mm:ss')}至${dayjs(end_date).format('YYYY-MM-DD HH:mm:ss')}还有课，请替换后再变更状态`
                }
            }
        }
        await updateStatus(body);
        ctx.body = {
            code: 1,
            msg: '状态变更成功'
        }
    } catch (error) {
        ctx.app.emit('error', error);
        ctx.body = {
            code: 0,
            msg: '状态变更失败，请稍后再试'
        }
    }
}

/**
 * 查询教师列表
 * @param {*} ctx 
 */
const searchList = async (ctx) => {
    try {
        const { count, rows } = await searchTeacherList(ctx.request.query);
        ctx.body = {
            code: 1,
            total: count,
            data: rows
        }
    } catch (error) {
        ctx.app.emit('error', error);
        ctx.body = {
            code: 0,
            msg: '教师列表数据查询失败'
        }
    }
}

/**
 * 添加紧急联系人
 * @param {*} ctx 
 */
const addEmergency = async ctx => {
    try {
        await addEmergencyContact(ctx.request.body);
        ctx.body = {
            code: 1,
            msg: '教师紧急联系人添加成功'
        }
    } catch (error) {
        ctx.app.emit('error', error);
        ctx.body = {
            code: 0,
            msg: '教师紧急联系人添加失败'
        }
    }
}

/**
 * 修改紧急联系人
 * @param {*} ctx 
 */
const updateEmergency = async ctx => {
    try {
        const obj = ctx.request.body;
        const id = obj.id;
        delete obj.id;
        await updateEmergencyContact(id, obj);
        ctx.body = {
            code: 1,
            msg: '教师紧急联系人修改成功'
        }
    } catch (error) {
        ctx.app.emit('error', error);
        ctx.body = {
            code: 0,
            msg: '教师紧急联系人修改失败'
        }
    }
}

/**
 * 添加紧急联系人
 * @param {*} ctx 
 */
const deleteEmergency = async ctx => {
    try {
        await deleteEmergencyContact(ctx.request.params.id);
        ctx.body = {
            code: 1,
            msg: '教师紧急联系人删除成功'
        }
    } catch (error) {
        ctx.app.emit('error', error);
        ctx.body = {
            code: 0,
            msg: '教师紧急联系人删除失败'
        }
    }
}

/**
 * 获取紧急联系人列表
 * @param {*} ctx 
 */
const getEmergencyList = async ctx => {
    try {
        const data = await getEmergencyContacts(ctx.request.params.id);
        ctx.body = {
            code: 1,
            data
        }
    } catch (error) {
        ctx.app.emit('error', error);
        ctx.body = {
            code: 0,
            msg: '教师紧急联系人获取失败'
        }
    }
}

/**
 * 搜索有效列表
 * @param {*} ctx 
 */
const searchAvailableList = async ctx => {
    try {
        const [data, total] = await searchAvailableTeacherList(ctx.request.query);
        ctx.body = {
            code: 1,
            total,
            data
        }
    } catch (error) {
        ctx.app.emit('error', error);
        ctx.body = {
            code: 0,
            msg: '教师列表数据查询失败'
        }
    }
}

/**
 * 搜索教师状态列表
 * @param {*} ctx 
 */
const searchTeacherStatus = async ctx => {
    try {
        const [data, total] = await searchStatus(ctx.request.query);
        ctx.body = {
            code: 1,
            total,
            data
        }
    } catch (error) {
        ctx.app.emit('error', error);
        ctx.body = {
            code: 0,
            msg: '教师状态列表数据查询失败'
        }
    }
}

module.exports = {
    add,
    login,
    update,
    addRoles,
    searchList,
    changeStatus,
    addEmergency,
    updatePassword,
    deleteEmergency,
    updateEmergency,
    updateMyPassword,
    getEmergencyList,
    validTeacherRigths,
    searchAvailableList,
    searchTeacherStatus
}